home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Your Choice 3
/
Your Choice Software Collection 3.iso
/
prgmming
/
fsprite3
/
fsprite3.doc
< prev
next >
Wrap
Text File
|
1994-04-28
|
34KB
|
754 lines
FastSPRITE3 - A Fast VGA Gamepack for Turbo Pascal Programmers
By Warren Steven Riley Jr.
Copyright 1992,1994
I have always wanted to write games. Even though IBM compatibles
have never been perfectly suited for writing games they have always
been the machine that I wanted to program for. When the VGA standard
became available I was thrilled. The 320x200 mode was perfectly suited
for game development. 256 colors made all the difference. I soon
realized it wasn't going to be as easy as I expected. The VGA standard
forced you to have software put every pixel of graphics on the screen
manually. This proved to be extremely s-l-o-w. I looked everywhere
for a set of programming routines that would be fast and expedite my
game development process. I couldn't really find anything at the time.
So I began writing FastSPRITE. FastSPRITE is a Turbo Pascal unit that
is extremely fast.
I first messed around with writing routines in conventional
assembly language. The technique used involved a machine language
routine that picked up a pixel from the sprite's data definition and
after deciding how to mask it would put it's pixel in it's appropriate
place. This was good but then I came up with an idea to make it nearly
twice as fast. I compiled the sprites so the speed could be maximized.
This created a noticeable improvement and speed and was the core of
FastSPRITE.
(Distribution and Registering info are at the end of this document)
--------------------------------------------------------------------
--------------------|Introduction|----------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
FSPRITE3.TPU is a Turbo Pascal 7.0 Unit that can be linked in to
your Turbo Pascal programs to write games. It includes a number of
useful sprite and graphics functions that are essential to writing a
good game. The technique used to create sprites that are smooth and
seamless involve creating two virtual screens. These screens are the
MID and BACK screens. Using this three tier approach fast "Super
Nintendo" graphics can be created. These graphics are smooth and
"flicker free". Without the two extra virtual screens multi-maskable
sprite(20+) games with a full background would not be easily
maintained. These two screens do immediately steal 128k of memory but
are well worth it in the end.
The interface for the FSPRITE3 TPU is given in the file
FSPRITE3.INT. This file contains all the necessary information for
writing a game using FSPRITE3. First I will give a brief explanation
of the usage of the sprite variables and functions.
Essentially all sprites in the shareware version of FSPRITE3 are
stored in SPF files. The format for these files is simple. The X and
Y sizes are stored in the first two bytes followed by a simple left to
right top to bottom bit dump of the image. The list of Sprites your
program will use is stored in a text data file. This text data file
can have any name and simply lists each sprite on a separate line until
all sprites are listed.
The format is as follows:
SPRITEXX.SPF
SAMPLEXX.SPF
MOONUNIT.SPF
etc.
The next process optionally involves converting the data file to a
PASCAL include file. This step is not necessary and is gone over in
detail later.
The first thing you introduce into your code is the SETGRAPH
routine. This does nothing more than initialize the 320x200 256 color
mode. It calls the interrupt to set up this graphics mode $13. The
READSPRITES(FILENAME) command follows and the file name it uses is the
text data file listing all the sprite SPF files used in the game. All
of these files must reside in the current directory. After all sprites
have been loaded you issue the COMPILE command. This doubles the speed
of your sprites. Even though this routine isn't absolutely necessary
it is highly recommended. At this point the sprites definitions are
all loaded into the SPRITE data type and the compiled sprites are all
loaded into the COMPILEDSPRITES data type. The compiled sprites are
actually little machine language programs that are created at run-time
to speed up sprite usage.
Even though you have all the sprite "pictures" in memory you
probably don't want to display all of them at the same time. The
SPRITE data type is merely a bank of sprite images. The sprites you
see on the screen work with a variable called ONSCREEN. The ONSCREEN
variable lists the sprites you are currently viewing. You tell each
ONSCREEN sprite where its definition is coming from in the SPRITES data
bank. You tell ONSCREEN.NUM which definition it is using, ONSCREEN.X
and ONSCREEN.Y where that sprite will appear on the screen and
ONSCREEN.ON if the sprite is visible or not. It may sound a little
confusing at first but makes sense as you work with it. The variable
OS contains the number of sprites that are being displayed on the
screen. The number of sprites on screen is one less that the last
ONSCREEN[XXX] used where XXX is the number of the referenced ONSCREEN
element.
After you have all this set up you load the palette when you use a
palette different than the default. READVGAPALETTE(FILENAME) is the
routine to to read a palette from a file. The file palette is a
straight dump of 256 RGB values each RGB value being a byte a piece.
Next you would probably want to load a background file from disk and
put it in the 64k BACK screen. After everything is ready in the main
loop simply execute the SHOW command to update the sprites on the
screen. And with that you have complete game potential.
--------------------------------------------------------------------
----------------|Interface Breakdown|-------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
Here each part of the TPU interface will be explained and broken
down. First the complete interface will be shown and then each part
will be broken down piece by piece.
Unit FSPRITE3;
interface
Uses crt,Dos;
Const MaxSpriteMemSize=20000; {Maximum Sprite Sizing}
SpritesCompiled:boolean=false;
FullScreenCopy:boolean=false;
TileMode:boolean=false;
ALTKEY=8;
CTRLKEY=4;
LEFTSHIFTKEY=2;
RIGHTSHIFTKEY=1;
CAPSLOCK=64; NUMLOCK =32; SCROLLLOCK=16;
type ColorValue = record RED,GREEN,BLUE: shortint; end;
PaletteType = array [0..255] of ColorValue;
SpriteGrid = Array [0..maxspritememsize] of byte;
SpriteGridPointer = ^SpriteGrid;
Sprite = record
Sx,Sy:byte;
Def:SPRITEGRIDPOINTER;
end;
SpritePointer = ^Sprite;
GraphicScreen = Array[0..203,0..319] of byte;
ScreenPointer = ^GraphicScreen;
OnScreen_Part_Type=record num:word;on:boolean;x:integer;y:integer;end;
OnScreenType=Array[0..100] of OnScreen_Part_Type;
var XKeyLocation:byte absolute $0040:$0017;
SpriteFileNames:ARRAY[0..200] OF STRING[12];
OS,NumberSpriteDefs:integer;
Sprites:Array[0..200] of SpritePointer;
OnScreen:OnScreenType;
Back,Mid:ScreenPointer;
Act:GraphicScreen absolute $A000:0000;
FKEY:array[0..255] of boolean; {Array for keyboard buffer}
Procedure killbuff;
Procedure startfkey;
Function xkey(LookFor:byte):boolean;
procedure Loadpalette(passname:string; var p:palettetype);
procedure SetVGAPalette(var tp:PaletteType);
procedure ReadVGApalette(var tp: PaletteType);
procedure SetGraph; Inline($B8/$13/0/$CD/$10);
procedure ReadSprites(FName:String);
procedure Compile;
procedure Show;
Const MaxSpriteMemSize=20000; {Maximum Sprite Sizing}
This constant is the maximum size in byte that a sprite can
possibly take up.
____________________________________________________________________
------------------- CONSTANTS --------------------------------------
SpritesCompiled:boolean=false;
This variable is TRUE when the sprites have been compiled FALSE
otherwise.
____________________________________________________________________
FullScreenCopy:boolean=false;
This variable is true when the entire middle screen will be lifted
to the active screen in the SHOW routine. Generally this variable is
set to false at all times. By only copying the sprites a better speed
can be maintained. The only time you would want to lift the entire MID
screen is when almost all of its data is changing.
____________________________________________________________________
TileMode:boolean=false;
Special mode not addressed at all in the shareware version.
____________________________________________________________________
ALTKEY=8;
CTRLKEY=4;
LEFTSHIFTKEY=2;
RIGHTSHIFTKEY=1;
CAPSLOCK=64; NUMLOCK =32; SCROLLLOCK=16;
These constants can be used in the FKEY extra key reading routine
to reference their keys. These "special" keys can be accessed by using
their contents with the FKEY routine.
____________________________________________________________________
------------------ TYPES -------------------------------------------
type ColorValue = record RED,GREEN,BLUE: shortint; end;
COLORVALUE is a type used for each entry in the palette. It is the
generic RGB holder for 256 color paletted modes. Each R,G,B can hold a
value from 0 to 63.
____________________________________________________________________
PaletteType = array [0..255] of ColorValue;
A type that includes an entire VGA working palette.
____________________________________________________________________
SpriteGrid = Array [0..maxspritememsize] of byte;
The SPRITEGRID is basically a straight array of sprite data used by
each SPRITES[XX].DEF entry.
____________________________________________________________________
SpriteGridPointer = ^SpriteGrid;
SPRITEGRIDPOINTER is the actual dynamically allocated pointer that
is used by each SPRITES[XX].DEF entry. Each sprite only allocates as
much memory as it uses. The dynamic approach is absolutely necessary
so that no room is wasted.
____________________________________________________________________
Sprite = record
Sx,Sy:byte;
Def:SPRITEGRIDPOINTER;
end;
The Sprite data type is where sprites read in using the
READSPRITES[FILENAME] procedure are stored before they are compiled.
It allocates their X and Y sizes and their definition pointer.
____________________________________________________________________
SpritePointer = ^Sprite;
SpritePointer is the data type that establishes a dynamic pointer
link with the SPRITE record.
____________________________________________________________________
GraphicScreen = Array[0..203,0..319] of byte;
This is the basic screen type for accessing screen data.
____________________________________________________________________
ScreenPointer = ^GraphicScreen;
This is a pointer.
____________________________________________________________________
OnScreen_Part_Type=record num:word;on:boolean;x:integer;y:integer;end;
The ONSCREEN array uses this type for each individual on-screen
sprite.
____________________________________________________________________
OnScreenType=Array[0..100] of OnScreen_Part_Type;
This type is for the ONSCREEN variable.
____________________________________________________________________
----------------- VARIABLES ---------------------------------------
var XKeyLocation:byte absolute $0040:$0017;
This location is where the extra key presses are stored. It is
used by the XKEY routine.
____________________________________________________________________
SpriteFileNames:ARRAY[0..200] OF STRING[12];
This array stores the names of the actual sprites read in by
READSPRITES(FILENAME) in the order they were read in. It has a one to
one correlation with the SPRITES[XX] variable.
____________________________________________________________________
OS,NumberSpriteDefs:integer;
The OS variable holds the number of active (on and off) ONSREEN
elements. It's number is equal to the last ONSCREEN[XX] value used.
The NUMBERSPRITEDEFS variable records the number of sprite
definitions that were read in using the READSPRITES[FILENAME] routine.
____________________________________________________________________
Sprites:Array[0..200] of SpritePointer;
SPRITES is the actual array of sprite pointer where the sizex,
sizey and sprite definition is stored.
____________________________________________________________________
OnScreen:OnScreenType;
ONSCREEN is the actual variable that holds the information on the
sprites currently on the screen including definition number, X
position, Y position, etc.
____________________________________________________________________
Back,Mid:ScreenPointer;
These variables are the dynamic links to the extra screens used to
hold graphic screen information necessary for the "flicker free" set-
up.
____________________________________________________________________
Act:GraphicScreen absolute $A000:0000;
This is the actual array used for all the active screen sprite
activity. It points to the beginning of graphics memory.
____________________________________________________________________
FKEY:array[0..255] of boolean; {Array for keyboard buffer}
This is an array that is used to detect keypresses using the FKEY
routine. Once FKEY is intialized it can detect keypressed of all keys,
even when more than one key is being pressed simultaneously.
____________________________________________________________________
----------Procedures and Functions----------------------------------
Procedure killbuff;
This procedure must be used once the FKEY interrupt routines are
started to "suck up" the extra keypresses.
____________________________________________________________________
Procedure startfkey;
This procedure starts the FKEY interrupt routines that allow
sophisticated keypress routines for games to be implemented. It can
check for multiple keypresses and doesn't have a buffer. When you use
it the FKEY variable is constantly updated to tell you all the keys
that are being pressed at exactly that instant.
____________________________________________________________________
Function xkey(LookFor:byte):boolean;
This is a special key handler that is built specifically for the
shift, alt, ctrl and lock keys. It can be emulated with FKEY but in
some respects is even better for these particular keys. Especially for
lock states it is very useful. You pass it a key to look for and it
tells you TRUE or FALSE its state.
____________________________________________________________________
procedure Loadpalette(passname:string; var p:palettetype);
This procedure loads the palette in passname string from disk into
the p variable that is of palette type.
____________________________________________________________________
procedure SetVGAPalette(var tp:PaletteType);
This uses a palette type variable to set the current VGA palette.
____________________________________________________________________
procedure ReadVGApalette(var tp: PaletteType);
This reads the current VGA palette into a variable of palettetype.
____________________________________________________________________
procedure SetGraph; Inline($B8/$13/0/$CD/$10);
This initializes the 320x200 256 color graphics mode.
____________________________________________________________________
procedure ReadSprites(FName:String);
This routine read a sprite list in from a text data file using the
names provided in that file to load SPF files into the SPRITES variable
structure.
____________________________________________________________________
procedure Compile;
Compiles the sprites for maximum speed creating a machine language
routine that handle sprite placement much more efficiently than a
traditional machine language sprite data handler program. The data and
code are actually melded together.
____________________________________________________________________
procedure Show;
Call this routine to update the latest sprite positions.
--------------------------------------------------------------------
----------------|Technique & Theory|--------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
The FSPRITE3 routines are built to maximize performance while still
giving flexibility. They provide especially fast animation for games
allowing overlapping sprites and easy use of background.
The root of the routines uses a three level screen structure, each
level being 64k. The first level is the BACK level and holds the
background of the screen to be seen. The second level is a MID screen
where the background is restored and the fresh compiled sprite
definitions are stamped. By stamping these definitions on a screen
that is not active "flicker" is eliminated. The third screen is the
ACTive screen and is the one that is actually seen. The sprites are
lifted from the MID screen to the ACTive screen and the process is
done. All of this takes place every time the SHOW routine is called.
Sprite utilization for the end program is reasonably
straightforward. A text data file must be constructed that contains
the names of all the sprite definition files that are to be loaded in.
This list can be turned into an include file for pascal compilation
using the DAT2INC.EXE program provided. Whenever you add new sprites
to the text data file use DAT2INC.EXE. The program only has one
parameter and that is the name of the file to be converted. Do not add
the extension because DAT2INC assumes it.
Once this include file has been created use the Turbo Pascal
include command to add it into your program. Don't actually slap the
text directly into your source; instead keep it as another file. At
some point you will update this file and it is easily dealt with as a
separate include file. By adding this file to your program you get the
added bonus of being able to refer to sprites definitions directly by
name. For example say you had these SPF files used in your program:
FIREBALL.SPF
FIREBAL2.SPF
FIREBAL3.SPF
MAN1.SPF
MAN2.SPF
MAN3.SPF
DAT2INC would make an include file that looks like this:
CONST FIREBALL=0;
FIREBAL2=1;
FIREBAL3=2;
MAN1=3;
MAN2=4;
MAN3=5;
Notice that the .SPFs do fall off. By making this include file you
can address sprite definitions in your code by name. This is extremely
useful when telling the active ONSCREEN sprites what they look like in
ONSCREEN.NUM. Make sure all the sprite files are in the same
directory. The registered version allows you to roll-up all the SPF
files into one big file.
Now you are set. In your code the next thing you must do is add
the SETGRAPH to initialize the graphics mode. After that you want to
use the READSPRITES procedure to read your SPF files off the disk and
into memory. They are all stored in the SPRITES data array. Using the
COMPILE procedure after READSPRITES just about doubles the speed of
your sprite code. It does take memory, so in some cases may not be
used. I almost always use it.
It works by turning the sprite data into actual machine language
code. Each sprite has its own tiny, specially geared machine language
program. Most sprite routines use a machine language loop that is the
same for every sprite and requires figuring out which pixels to mask
and which not to mask. This is a very small number of opcodes, but it
is DONE EVERY SINGLE PIXEL. Even when you repeat something minor, say
10,000 times every step of animation, things start to slow down. There
is no figuring out with my routines. Once compiled on the fly they
know which pixel to use and which not to use. Special attention paid
to each and every sprite. Isn't that nice.
The mask that sprites use is color 0, whatever that may be.
Usually, by default it is black so if you actually want to display
black assign another color in the palette to the RGB values of black.
Once all the sprites have been compiled you'll want to set up the
background screen. You can erase it or assign a graphics screen to it.
If you erase it I find the easiest way to do so the most efficiently is
to use the turbo pascal FILLCHAR routine. This statement will clear
the background screen:
FILLCHAR(BACK^,320*200,0)
Remember that the BACK screen is addressed BACK^ because it has
been dynamically allocated using the NEW command in the FSPRITE3 TPU.
Whenever you access the back or middle screens it will be through a
pointer. The active screen does not work this way, it is direct.
The next step is to clear out the middle screen. At this point I
usually copy the zeros from the back screen:
MID^:=BACK^
The same is true for the active screen:
ACT:=BACK^
At this point you have a blank screen and some sprites loaded and
compiled in memory. Maybe you would load a bitmap screen from disk:
procedure load_screen(filename:string;var inscreen:graphicscreen);
begin
ASSIGN (fFile, filename); {Read Bitmap screen from file}
RESET (fFile, 1);
BLOCKREAD (fFile, BOGUS_BUFFER, 7);
BLOCKREAD (fFile, inscreen, 64000);
CLOSE (fFile);
end;
. . . . .
load_screen('FILENAME',BACK^)
In this case I loaded a bitmap that had been clipped out of
AutoDesk Animator using a screen capture utility. The save format for
this utility stored an extra seven bytes before the actual bit map data
is read in. A palette could then be loaded:
PROCEDURE LOAD_PALETTE(FILENAME:STRING;VAR INPAL:PALETTETYPE);
BEGIN
ASSIGN (pfile, FILENAME); {Read screen palette from disk}
RESET (pfile, 1);
BLOCKREAD (pfile, BOGUS_BUFFER, 7);
BLOCKREAD (pfile, INPAL, 768);
CLOSE (pfile);
END;
. . . . .
LOAD_PALETTE('FILENAME',P);
And then actually make it the active palette:
SET_VGA_PALETTE(p);
Because we load a bitmap screen to BACK^ we have to move it to the MID
screen and the ACTive screen:
MID^:=BACK^;
ACT:=BACK^;
I wrote a new load_palette command above because the loaded palette
also has a tossable header at the beginning. At this point we are
ready to start focusing on the sprites themselves.
We could next set up the sprites we would see onscreen:
ONSCREEN[0].NUM:=MAN1;
This statement tells the first sprite that is on the screen to get
its information from definition number MAN1 where MAN1 is a constant
our include file set to 3 earlier.
ONSCREEN[0].ON:=TRUE;
ON set to TRUE tells us that this sprite will be visible now. When
the sprite is turned off it can easily be set to false;
ONSCREEN[0].X:=100;
ONSCREEN[0].Y:=100;
This tells the SHOW routine that the first sprite will be at
location 100,100. We set up all the rest of the sprites in a similar
manner:
FOR I:=1 to 40 DO
BEGIN;
ONSCREEN[I].NUM:=FIREBALL;
ONSCREEN[I].X:=RANDOM(320);
ONSCREEN[I].Y:=RANDOM(200);
ONSCREEN[I].ON:=TRUE;
END;
Here forty more sprites have been added and they all look like
fireballs. They start at random locations and are all turned ON.
The last step needed before the main program loop can be entered is to
set the number if onscreen sprite definitions so FSPRITE3 knows how
many sprites to look through.
OS:=40;
This is one less than the actual number of sprites, or simply the
last number addressed in the onscreen array(40). Our sample program
now only needs to call show to display them:
REPEAT;
FOR I:=1 TO 40 DO
BEGIN
INC(ONSCREEN[I].X,3);
IF ONSCREEN[I].X>320 THEN
ONSCREEN[I].X:=-20;
END;
SHOW;
UNTIL KEYPRESSED;
One consideration that must be kept in mind is that sprites will
only erase their old positions if they are designed and moved with
cleanup in mind. If you have sprites that are going to skip three
pixels every time they move their corresponding sprites must have at
least a three pixel "clear" barrier or else they will trail and streak.
If a sprites definition is seen as D and clear spaces as - a sprite
that wants to skip three pixels each round of movement would look like
this:
---------------------------
---------------------------
---------------------------
---DDDDDDDDDDDDDDDDDDDDD---
---DDDDDDDDDDDDDDDDDDDDD---
---DDDDDDD--------DDDDDD---
---DDDDDDDDDDDDDDDDDDDDD---
---------------------------
---------------------------
---------------------------
The middle dashes represent a "see-through" piece of sprite in the
middle. If you decide you want to wildly move the sprites around or
wish to forget about the buffer, you can but you have to manually clean
up the sprite trails.
This is a very simple set of code blocks but does demonstrate the
necessary basic principles of FSPRITE3 game program design.
--------------------------------------------------------------------
-------------|Registration|-----------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
You are allowed a thirty day trial period to exam FSPRITE3 and see
if you would like to register it. After that period you will be
required to register it. When you register it you will receive:
1 The latest 'registered' version of FSPRITE
2 Additional functions and procedures unavailable in the shareware
version
3 A comprehensive manual describing FSPRITE's capabilities, syntax,
descriptions, examples etc.
4 A removal of all the 'nag' messages.
5 More examples and all the other demonstration goodies that can
fit on a disk (much more than can be distributed in a 'small'
modem shareware file).
6 A full registered version of the SPREDIT sprite editor program
and everything that it's registered features entails.
7 The ability to freely distribute the code you create from your
programs built using FSPRITE for fun and of course profit
8 The ability to write Borland Pascal code that use DPMI (dos
protected mode interface) routines to break the one meg barrier.
Using Borland Pascal I can easily write code that takes 4,5 or 6
meg of ram!
To register simply send $45 check or money order to:
Steve Riley
P.O.Box #21
Herndon, VA 22070-9998
Make check payable to Steve Riley.
Make sure and give us your full name and address.
Make sure and specify FSPRITE.
Make sure and specify disk format.
(If you choose 360k 5 1/4 inch floppy it will be mailed on two
disks for an extra fee of one dollar)
If you would like the actual source code to the FSPRITE3 unit
itself send a total of $120 to the address above and you will also
recieve the source code.
--------------------------------------------------------------------
--------------------|DISTRIBUTION|----------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
These files may be freely distributed as long as all the files are
distributed as is and intact. All of the files must be present. The
file list is at the end of this DOC. No profit can come from the sale
of this product. The only acceptable payment is reimbursement for
distribution costs. The non-shareware registered version of this
product should never be given out under any circumstances. The source
code to the FSPRITE unit itself should never be given out under any
circumstances.
--------------------------------------------------------------------
--------------------|DISCLAIMER|------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
FSPRITE3 is provided AS IS without any warranty, expressed or implied.
White Obsidian Software shall not be liable for ANY damages,
whether direct, indirect, special, or consequential arising from a
failure of this FSPRITE unit or accompanying files to operate in a
manner desired by the user. White Obsidian Software shall not be held
responsible for any damage which may by caused by use of this unit or
its accompanying files. White Obsidian Software will not be held
responsible for ANY damages related to the use of these files.
Enjoy,
Steve Riley
April 29, 1994.
Filelist:
FINDFKEY PAS 1,088 04-28-94 4:25a
BEGIN BLD 64,007 02-16-92 12:44a
SCREEN00 BLD 64,007 02-15-92 8:51p
SCREEN01 BLD 64,007 02-15-92 5:17a
DIGIT DAT 1 04-28-94 6:43a
ORDER DOC 1,376 04-28-94 4:18a
README DOC 5,228 04-28-94 4:56a
BEGIN PLT 777 02-16-92 12:44a
SCREEN00 PLT 777 02-15-92 8:51p
SCREEN01 PLT 777 02-15-92 5:17a
GOBATME SMP 8,000 11-14-91 4:01a
FSPRITE3 DOC 30,700 04-28-94 6:19a
GOLIKEM1 SMP 6,000 11-14-91 6:20p
GOLIKEM2 SMP 6,000 11-14-91 3:02a
GOLIKEM3 SMP 6,000 11-14-91 5:16p
GOLIKEM4 SMP 6,000 11-14-91 5:17p
D EXE 33,904 04-28-94 5:41a
REALBASE PAS 20,418 04-28-94 4:25a
FILE_ID DIZ 311 04-28-94 5:11a
REALBOMB PAS 4,300 04-28-94 4:51a
BOMBER1 SPF 578 02-15-92 7:32p
BOMBER2 SPF 578 02-15-92 7:36p
BOMBER3 SPF 578 02-15-92 7:36p
BOMBER4 SPF 578 02-15-92 7:37p
BOOM1 SPF 427 02-14-92 11:45p
BOOM2 SPF 427 02-14-92 11:46p
BOOM3 SPF 427 02-14-92 11:46p
BOOM4 SPF 427 02-14-92 11:55p
BOX1 SPF 422 02-15-92 11:18p
BOX2 SPF 422 02-15-92 11:28p
BOX3 SPF 422 02-15-92 11:57p
BOX4 SPF 422 02-15-92 11:59p
GTEST DAT 501 04-21-94 3:04a
ESPHERE1 SPF 427 02-15-92 8:21p
ESPHERE2 SPF 427 02-15-92 8:19p
ESPHERE3 SPF 427 02-15-92 8:18p
ESPHERE4 SPF 427 02-15-92 8:16p
EYE1 SPF 427 02-15-92 3:08p
EYE2 SPF 427 02-15-92 3:11p
EYE3 SPF 427 02-15-92 3:14p
EYE4 SPF 427 02-15-92 3:17p
REALVARS PAS 11,659 04-28-94 4:26a
FACE1 SPF 602 02-15-92 7:02p
FACE2 SPF 602 02-15-92 7:03p
FACE3 SPF 602 02-15-92 7:04p
FACE4 SPF 602 02-15-92 7:05p
FIGHTER SPF 422 02-15-92 2:28a
FIGHTER1 SPF 422 02-15-92 9:00p
FIGHTER2 SPF 422 02-15-92 8:59p
FIGHTER3 SPF 422 02-15-92 9:06p
SPRDEVAL DOC 25,909 04-28-94 4:43a
LIVES SPF 158 02-15-92 1:56p
MISSL SPF 38 02-15-92 6:21a
MOTH1 SPF 422 02-15-92 11:18p
MOTH2 SPF 422 02-15-92 11:28p
MOTH3 SPF 422 02-15-92 11:57p
MOTH4 SPF 422 02-15-92 11:59p
PURPFIRE SPF 42 08-14-91 2:01p
LFIGHTER SPF 422 04-21-94 3:22a
SKULL SPF 602 02-15-92 8:28p
SNAKBALL SPF 274 02-15-92 7:09p
SNAKHOLE SPF 274 02-15-92 7:10p
SPHERE1 SPF 427 02-15-92 6:14a
SPHERE2 SPF 427 02-15-92 6:15a
SPHERE3 SPF 427 02-15-92 6:15a
SPHERE4 SPF 427 02-15-92 6:16a
TEMP SPF 427 02-15-92 5:57a
REALEVIL PAS 7,578 04-28-94 4:53a
VERTEBRA SPF 274 02-15-92 5:49a
RUNME EXE 29,200 04-28-94 8:05p
DAT2INC PAS 736 04-17-94 7:12p
DAT2INC EXE 4,176 04-17-94 7:12p
GTEST INC 664 04-21-94 3:04a
REALITY PAS 856 04-28-94 4:24a
DBOMBER SPF 578 04-21-94 8:10p
FSPRITE3 TPU 25,168 04-26-94 6:20a
FSPRITE3 INT 2,144 04-28-94 8:12p